#ifndef CONFIGURATION_H
#define CONFIGURATION_H
#include <string>
#include <iostream>
#include <mutex>
#include <fstream>
#include <map>

using namespace::std;

class Configuration
{

public:
    //禁用拷贝构造和移动赋值确保唯一性
    Configuration(const Configuration&)=delete;
    Configuration& operator=(const Configuration&)=delete;
    //设置为静态唯一获取
    static Configuration&getInstance()
    {
        static Configuration instance;
        return instance;
    }
    //加载配置文件（返回是否成功）
    bool loadConfig(const std::string &filePath)
    {
        lock_guard<mutex>lock(_mutex);
        ifstream file(filePath);
        if(!file.is_open())
        {
            cerr<<"Failed to open config file"<<filePath<<endl;
            return false;
        }
        _configMap.clear();
        string line;
        while(getline(file,line))
        {
            //跳过注释（#开头）和空白行
            if(line.empty()||line[0]=='#')
            {
                continue;
            }
            size_t eqPos=line.find(" \t");
            if(eqPos==string::npos)
            {
                continue;
            }
            string key=trim(line.substr(0,eqPos));
            string value=trim(line.substr(eqPos+1));
            if(!key.empty()&&!value.empty())
            {
                _configMap[key]=value;
            }
        }
        file.close();
        _isLoaded=true;
        return true;
    } 
    string getString(const string &key,const string &defaultVal="")const
    {
        lock_guard<mutex>lock(_mutex);
        auto it=_configMap.find(key);
        return (it!=_configMap.end()?it->second:defaultVal);
    }
    int getInt(const string &key,int defaultVal=0)const
    {
        lock_guard<mutex>lock(_mutex);
        auto it=_configMap.find(key);
        if(it==_configMap.end())
        {
            return defaultVal;
        }
        //try后面跟的是监控区域如果报异常就会跳到catch
        //然后返回默认值
        try
        {
            return stoi(it->second);
        }
        catch (...)
        {
            return defaultVal;
        }
    }
    // 检查配置是否已加载
    bool isLoaded() const
    {
        return _isLoaded;
    }
private:
    //私有化构造函数（禁止外部实例化）
    Configuration():_isLoaded(false){}
    string trim(const string &str)const
    {
        size_t start=str.find_first_not_of(" \t");
        size_t end=str.find_last_not_of(" \t");
        if(start==string::npos)
        {
            return "";
        }
        return str.substr(start,end-start+1);
    }
private:
    //存储配置键值对例如ip 127.0.0.1  
    map<string,string>      _configMap;
    //判断配置是否已加载
    bool                    _isLoaded;
    //线程安全锁 设置为mutable是因为
    //配置信息声明为const不可以在里面加锁
    //使用mutable后可以在里面加锁
    mutable mutex           _mutex;
};


#endif

